﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Logs;

namespace Communication.Tcp {
    /// <summary>
    /// Tcp服务端
    /// </summary>
    public class AsyncTcpServer {
        /// <summary>
        /// 本地端口
        /// </summary>
        private int port = 0;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="port">本地端口</param>
        public AsyncTcpServer(int port) {
            this.port = port;
        }

        /// <summary>
        /// 启动Tcp服务
        /// </summary>
        public void StartServer() {
            Thread listenerThread = new Thread(() => {
                IPAddress ip = IPAddress.Any;   
                TcpListener listener = new TcpListener(ip,this.port);
                listener.Start();   //启动监听
                Log.Info(string.Format("启动Tcpserver监听！地址：{0}",listener.LocalEndpoint));
                while(true) {
                    TcpClient client = listener.AcceptTcpClient();  //接收连接请求
                    Log.Info(string.Format("客户端已连接! 地址：{0}",client.Client.RemoteEndPoint));
                    new RemoteClient(client);   //创建远程客户端
                }
            });
            listenerThread.IsBackground = true; 
            listenerThread.Start();
        }
    }

    /// <summary>
    /// 远程客户端类
    /// </summary>
    public class RemoteClient {
        private TcpClient client;
        private NetworkStream netStream = null;
        /// <summary>
        /// 读取缓冲区
        /// </summary>
        private byte[] readBuffer = null;
        /// <summary>
        /// 缓存大小
        /// </summary>
        private int bufferSize = 8192;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="client"></param>
        public RemoteClient(TcpClient client) {
            this.client = client;
            netStream = client.GetStream();
            readBuffer = new byte[bufferSize];
            AsyncCallback callBack = new AsyncCallback(ReadComplete);
            netStream.BeginRead(readBuffer,0,bufferSize,callBack,null);
        }

        /// <summary>
        /// 读取回调函数
        /// </summary>
        /// <param name="ar"></param>
        public void ReadComplete(IAsyncResult ar) {
            int bytesRead = 0;
            try {
                lock(netStream) {
                    bytesRead = netStream.EndRead(ar);
                }
                if(bytesRead == 0) {
                    throw new Exception("");
                }

                string msg = Encoding.Default.GetString(readBuffer,0,bytesRead);
                Console.WriteLine(msg);
                netStream.Write(readBuffer,0,bytesRead);    

                Array.Clear(readBuffer,0,readBuffer.Length);
                lock(netStream) {
                    AsyncCallback callBack = new AsyncCallback(ReadComplete);
                    netStream.BeginRead(readBuffer,0,bufferSize,callBack,null);
                }
            } catch(Exception ex) {
                if(netStream != null) {
                    netStream.Dispose();
                }
                client.Close();
                Console.WriteLine(ex.Message);
            }
        }
    }
}













